#include <stdio.h> 
#include <stdlib.h> 
#include <fcntl.h> /* open, close */
#include <unistd.h>

#include "contexts.h"
#include "posets.h"
#include "commondefs.h"

#include "debug.h"

#define CTXREDSEP ""

static Context context;


/* Reduce a context */
/* Remark : this is a wrong algorithm, so 
   if somebody wants to carry on,
   he is very welcome !!!
 */

Context *
reduce(Context * context)
{
  Listofsss jis=NULL,mis=NULL;
  Context * ret = NEW(Context);
  int index_ji,index_mi;
  struct lnode *index,*ptr_ji, *ptr_mi;
  Subset *ss_this;

  int ji,mi;

  FORALLMIIN(ji,context)
    {
      ss_this=ctx_ji_closure(context,ji);

      /* If this subset is already in the list, then
	 add only its name */
      if( (index=list_find(*ss_this,jis,ss_equal)) )
	ss_add_name(&index->el,ctx_ji_name(context,ji),CTXREDSEP);
      /* otherwise all the subset to it */
      else
	{
	  ss_add_name(ss_this,ctx_ji_name(context,ji),CTXREDSEP);
	  jis = list_add_element(*ss_this,jis);
	}
      
      ss_free(ss_this);
    }

  FORALLMIIN(mi,context)
    {
      ss_this=ctx_mi_image(context,mi);

      /* If this subset is already in the list, then
	 add only its name */
      if( (index=list_find(*ss_this,mis,ss_equal)) )
	ss_add_name(&index->el,ctx_mi_name(context,mi),CTXREDSEP);
      /* otherwise all the subset to it */
      else
	{
	  ss_add_name(ss_this,ctx_mi_name(context,mi),CTXREDSEP);
	  mis = list_add_element(*ss_this,mis);
	}
      
      ss_free(ss_this); 
    }


  ctx_init(ret,list_length(jis),list_length(mis));

  /* Set the names */
  index_ji=index_mi=0;
  FORALLIN(ptr_ji,jis)
    ctx_set_ji_name(ret,index_ji++,ss_name(&ptr_ji->el));
  FORALLIN(ptr_mi,mis)
    ctx_set_mi_name(ret,index_mi++,ss_name(&ptr_mi->el));
  

  /* Set the table */
  index_ji=0;
  FORALLIN(ptr_ji,jis)
    {
      index_mi=0;
      FORALLIN(ptr_mi,mis)
	{
	  if(ss_contained(&ptr_ji->el,&ptr_mi->el))
	    ctx_set_orthogonal(ret,index_ji,index_mi);
	  index_mi++;
	}
      index_ji++;
    }
  
  /* Set the name */
  {
    char buffer[100];
    
    snprintf(buffer,100-1,"%sreduced",ctx_name(context));
    ctx_set_name(ret,buffer);

  }
  /* Free allocated memory */
  list_free(jis);
  list_free(mis);

  return ret;
}

void
proc(void)
{
  Context *reduced;

  reduced = reduce(&context);
  ctx_print(reduced); 
  ctx_free(reduced);
}

int
main(int argc, char * argv[]){

  int fd = STDIN_FILENO; /**< input file descriptor */ 

  if(argc > 2)
    exit(EXIT_FAILURE);
  
  if(argc == 2)
    {
      if( (fd =open(argv[1],O_RDONLY)) < 0)
	exit(EXIT_FAILURE);
    }

  ctx_init(&context,0,0);
  ctx_parse(&context,fd);

  proc();

  exit(EXIT_SUCCESS);
}

